package com.cy.pj.sys.service.aspect;

import com.cy.pj.common.annotation.RequiredLog;
import com.cy.pj.sys.pojo.SysLog;
import com.cy.pj.sys.service.SysLogService;
import com.cy.pj.sys.util.IPUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
@Slf4j
public class SysLogAspect {
    //@Pointcut("bean(sysUserServiceImpl)")
    @Pointcut("@annotation(com.cy.pj.common.annotation.RequiredLog)")
    public void doLog(){} //方法内部不需要写任何代码，只是用于承载注解@Pointcut

    @Around("doLog()")
    public Object doAround(ProceedingJoinPoint joinPoint)throws Throwable{
        long t1 = System.currentTimeMillis();
        log.info("start {}",t1);
        try {
            Object result = joinPoint.proceed();
            long t2 = System.currentTimeMillis();
            log.info("end {}",t2);
            saveUserLog(joinPoint,t2-t1);
            return result;
        }catch (Throwable e){
            log.error("error {}",e.getMessage());
            throw e;
        }
    }

    @Autowired
    private SysLogService sysLogService;

    private void saveUserLog(ProceedingJoinPoint joinPoint,Long time) throws NoSuchMethodException, JsonProcessingException {
        String ip = IPUtils.getIpAddr();
        System.out.println(ip);
        String username="admin";
        //获取操作名
        MethodSignature ms = (MethodSignature)joinPoint.getSignature();

        Class<?> targetClass = joinPoint.getTarget().getClass();
        Method targetMethod = targetClass.getDeclaredMethod(ms.getName(),ms.getParameterTypes());
        RequiredLog requiredLog = targetMethod.getAnnotation(RequiredLog.class);
        String operation=requiredLog.operation();
        String method=targetClass.getName()+"."+targetMethod.getName();
        String params=new ObjectMapper().writeValueAsString(joinPoint.getArgs());

        SysLog log = new SysLog();
        log.setIp(ip);
        log.setUsername(username);
        log.setOperation(operation);
        log.setMethod(method);
        log.setParams(params);
        log.setTime(time);
        new Thread(){
            @Override
            public void run(){
                sysLogService.saveObject(log);
            }
        }.start();
    }

}
